#include "../mqserver/virtualHost.hpp"
#include <gtest/gtest.h>

// using ArgsMap = std::unordered_map<std::string, std::string>;
using ArgsMap = google::protobuf::Map<std::string, std::string>;  // 适应protobuf中的Map类型
class HostTest : public testing::Test
{
    void SetUp() override
    {
        // 声明交换机
        _host = std::make_shared<zhong::VirtualHost>("host1", "./data/host1/message/", "./data/host1/host1.db");
        _host->declareExchange("exchange1", zhong::ExchangeType::DIRECT, true, false, ArgsMap());
        _host->declareExchange("exchange2", zhong::ExchangeType::DIRECT, true, false, ArgsMap());
        _host->declareExchange("exchange3", zhong::ExchangeType::DIRECT, true, false, ArgsMap());
        // 声明队列
        _host->declareQueue("queue1", true, false, false, ArgsMap());
        _host->declareQueue("queue2", true, false, false, ArgsMap());
        _host->declareQueue("queue3", true, false, false, ArgsMap());
        // 进行绑定
        _host->bind("exchange1", "queue1", "news.music.#");
        _host->bind("exchange1", "queue2", "news.music.#");
        _host->bind("exchange1", "queue3", "news.music.#");

        _host->bind("exchange2", "queue1", "news.music.#");
        _host->bind("exchange2", "queue2", "news.music.#");
        _host->bind("exchange2", "queue3", "news.music.#");

        _host->bind("exchange3", "queue1", "news.music.#");
        _host->bind("exchange3", "queue2", "news.music.#");
        _host->bind("exchange3", "queue3", "news.music.#");

        // 发布消息
        _host->basicPublish("queue1", nullptr, "Hello World-1");
        _host->basicPublish("queue1", nullptr, "Hello World-2");
        _host->basicPublish("queue1", nullptr, "Hello World-3");

        _host->basicPublish("queue2", nullptr, "Hello World-1");
        _host->basicPublish("queue2", nullptr, "Hello World-2");
        _host->basicPublish("queue2", nullptr, "Hello World-3");

        _host->basicPublish("queue3", nullptr, "Hello World-1");
        _host->basicPublish("queue3", nullptr, "Hello World-2");
        _host->basicPublish("queue3", nullptr, "Hello World-3");
    }
    void TearDown() override
    {
        // _host->clear();
    }

public:
    zhong::VirtualHost::ptr _host;
};

/*注意以下测试模块均是独立的*/

// TEST_F(HostTest, initTest)
// {
//     ASSERT_EQ(_host->existExchange("exchange1"), true);
//     ASSERT_EQ(_host->existExchange("exchange2"), true);
//     ASSERT_EQ(_host->existExchange("exchange3"), true);

//     ASSERT_EQ(_host->existQueue("queue1"), true);
//     ASSERT_EQ(_host->existQueue("queue2"), true);
//     ASSERT_EQ(_host->existQueue("queue3"), true);

//     ASSERT_EQ(_host->existBinding("exchange1", "queue1"), true);
//     ASSERT_EQ(_host->existBinding("exchange1", "queue2"), true);
//     ASSERT_EQ(_host->existBinding("exchange1", "queue3"), true);

//     ASSERT_EQ(_host->existBinding("exchange2", "queue1"), true);
//     ASSERT_EQ(_host->existBinding("exchange2", "queue2"), true);
//     ASSERT_EQ(_host->existBinding("exchange2", "queue3"), true);

//     ASSERT_EQ(_host->existBinding("exchange2", "queue1"), true);
//     ASSERT_EQ(_host->existBinding("exchange2", "queue2"), true);
//     ASSERT_EQ(_host->existBinding("exchange2", "queue3"), true);

//     zhong::MessagePtr message1 = _host->basicConsume("queue1");
//     ASSERT_EQ(message1->payload().body(), std::string("Hello World-1"));

//     zhong::MessagePtr message2 = _host->basicConsume("queue1");
//     ASSERT_EQ(message2->payload().body(), std::string("Hello World-2"));

//     zhong::MessagePtr message3 = _host->basicConsume("queue1");
//     ASSERT_EQ(message3->payload().body(), std::string("Hello World-3"));

//     zhong::MessagePtr message4 = _host->basicConsume("queue1");
//     ASSERT_EQ(message4.get(), nullptr);
// }

// // 测试删除交换机
// TEST_F(HostTest, remove_exchange)
// {
//     _host->deleteExchange("exchange1");
//     ASSERT_EQ(_host->existBinding("exchange1", "queue1"), false);
//     ASSERT_EQ(_host->existBinding("exchange1", "queue2"), false);
//     ASSERT_EQ(_host->existBinding("exchange1", "queue3"), false);
// }

// // 测试删除队列
// TEST_F(HostTest, remove_queue)
// {
//     _host->deleteQueue("queue1");
//     ASSERT_EQ(_host->existBinding("exchange1", "queue1"), false);
//     ASSERT_EQ(_host->existBinding("exchange2", "queue1"), false);
//     ASSERT_EQ(_host->existBinding("exchange3", "queue1"), false);

//     zhong::MessagePtr message1 = _host->basicConsume("queue1");
//     ASSERT_EQ(message1.get(), nullptr);
// }

// 测试确认消息（删除消息）
TEST_F(HostTest, remove_message)
{
    zhong::MessagePtr message1 = _host->basicConsume("queue1");
    ASSERT_EQ(message1->payload().body(), std::string("Hello World-1"));

    zhong::MessagePtr message2 = _host->basicConsume("queue1");
    ASSERT_EQ(message2->payload().body(), std::string("Hello World-2"));

    zhong::MessagePtr message3 = _host->basicConsume("queue1");
    ASSERT_EQ(message3->payload().body(), std::string("Hello World-3"));
}

int main(int argc, char *argv[])
{
    testing::InitGoogleTest(&argc, argv);
    RUN_ALL_TESTS();
}